package com.self.ry.config;

import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * Copyright: Copyright (c) 2019
 *
 * @Description: ssh连接工具类
 * @version: v1.0.0
 * @author: my
 * @date: 2019/1/14 17:33
 * <p>
 * Modification History:
 * Date         Author          Version            Description
 * ---------------------------------------------------------*
 * 2019/1/14     my           v1.0.0               修改原因
 */
@Configuration
public class SSHConnection {
    private static final Logger LOGGER = LoggerFactory.getLogger(SSHConnection.class);

    @Autowired
    private RedisSSHSettings redisSSHSettings;

    @Autowired
    private MySQLSSHSettings mySQLSSHSettings;

    private Session redisSession = null;
    private Session sqlSession = null;

    @Value("${spring.redis.port}")
    int redisLocalPort;

    @Value("${spring.datasource.url}")
    String url;
    int sqlLocalPort;

    @PostConstruct
    public void init() {

        getRedisSession();
        getMySQLSession();
    }

    /**
     * Redis跳板转发session作成
     * @return
     */
    public Session getRedisSession() {
        LOGGER.info("===============getRedisSession start============");
        try {
            if (!redisSSHSettings.getEnable()) return null;
            JSch jSch = new JSch();
            // 获取session
            redisSession = jSch.getSession(redisSSHSettings.getUsername(), redisSSHSettings.getRemote(), redisSSHSettings.getPort());
            // 设置密码
            redisSession.setPassword(redisSSHSettings.getPassword());

            // 设置安全级别
            redisSession.setConfig("StrictHostKeyChecking", redisSSHSettings.getStrictKey());

            // 建立连接
            redisSession.connect();

            // 通过SSH连接到Redis机器上
            // 将请求转发到 redisSSHSettings.getRedisHost()上
            int forwardingL = redisSession.setPortForwardingL(redisLocalPort, redisSSHSettings.getRedisHost(), redisSSHSettings.getRedisPort());
            LOGGER.info("===============getRedisSession "+forwardingL+"============");
        } catch (JSchException e) {
            LOGGER.error(e.getMessage());
        }
        LOGGER.info("===============getRedisSession end============");
        return redisSession;
    }

    /**
     * SQL跳板转发session作成
     * @return
     */
    public Session getMySQLSession() {
        LOGGER.info("===============getMySQLSession start============");
        try {
            if (!mySQLSSHSettings.getEnable()) return null;
            JSch jSch = new JSch();
            // 获取session
            sqlSession = jSch.getSession(mySQLSSHSettings.getUsername(), mySQLSSHSettings.getRemote(), mySQLSSHSettings.getPort());
            // 设置密码
            sqlSession.setPassword(mySQLSSHSettings.getPassword());

            // 设置安全级别
            sqlSession.setConfig("StrictHostKeyChecking", mySQLSSHSettings.getStrictKey());

            // 建立连接
            sqlSession.connect();

            // 通过SSH连接到MYSQL机器上
            // 获取本地SQL端口号
            String[] strings = url.split(":");
            if (strings.length >= 4) {
                String[] split = strings[3].split("/");
                sqlLocalPort = Integer.valueOf(split[0]);
            }
            int forwardingL = sqlSession.setPortForwardingL(sqlLocalPort, mySQLSSHSettings.getSqlHost(), mySQLSSHSettings.getSqlPort());
            LOGGER.info("===============getMySQLSession "+forwardingL+"============");
        } catch (JSchException e) {
            LOGGER.error(e.getMessage());
        }
        LOGGER.info("===============getMySQLSession end============");
        return sqlSession;
    }

    /**
     * 关闭连接
     */
    @PreDestroy
    public void stop() {
        if (redisSession != null && redisSession.isConnected()) {
            redisSession.disconnect();
        }

        if (sqlSession != null && sqlSession.isConnected()) {
            sqlSession.disconnect();
        }
    }
}
